﻿using System.Collections.Concurrent;
using System.Diagnostics;
using RayDen.Library.Components.Surface;
using RayDen.Library.Core;
using RayDen.Library.Core.Primitives;

namespace RayDen.RayEngine.Engines.ManyLights
{
    public class Vpl
    {
        public Point HitPoint;
        public Normal GeoNormal;
        public Vector Wi;
        public RgbSpectrum ThroughtPut;
        public ISpectrum Spectrum;
        public ISurfaceMaterial Bsdf;
        public float VplWeight;
    }

    public class VplCollection
    {
        private readonly object b_lock = new object();

        private Vpl[] data;

        public int Count
        {
            get { return vpls.Count; }
        }

        public bool Full
        {
            get { return this.vpls.Count >= max; }
        }

        public Vpl[] Data
        {
            get
            {
                if (!Full)
                    return null;
                return (data ?? (data = ToArray()));
            }
        }

        private ConcurrentBag<Vpl> vpls;
        protected int max;

        public VplCollection(int maxVpls)
        {
            vpls = new ConcurrentBag<Vpl>();
            max = maxVpls;
        }

        public void Add(Vpl vpl)
        {
            if (vpl.GeoNormal.IsZero())
            {
                Debugger.Break();
            }
            this.vpls.Add(vpl);
            if (Full)
            {
                data = ToArray();
            }
        }

        private FastRandom rnd = new FastRandom();

        public Vpl[] GetRandomVpls(int n)
        {
            Vpl[] res = new Vpl[n];
            
            for (int i = 0; i < n; i++)
            {
                var np = rnd.Next(0, data.Length);
                //this.vpls.TryPeek(out res[i]);
                res[i] = data[np];
            }
            return res;
        }



        public void GetRandomVpl(out Vpl vpl)
        {
            var np = rnd.Next(0, data.Length);
            //this.vpls.TryPeek(out res[i]);
            vpl= data[np];
        }

        public Vpl[] ToArray()
        {
            return this.vpls.ToArray();
        }

    }
}
